#define _CRT_SECURE_NO_WARNINGS
#include"SList.h"
//打印节点:
void SLTPrint(node* phead)
{
	node* cur = phead;
	while (cur)
	{
		printf("%d -> ", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

//申请一个新的节点并添加数据:
node* SLTBuyNode(SLDatatype x)
{
	node* newnode = (node*)malloc(sizeof(node));
	if (newnode == NULL)
	{
		perror("malloc fail!\n");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

//尾插(如果是空链表的话，要改变plist的值让它指向第一个节点，需要二级指针,但是如果是非空链表的话，就不需要改变plist了，要一直让他指向第一个节点):
void SLTPushBack(node** pphead, SLDatatype x)
{
	assert(pphead);
	//空链表和非空链表:
	if (*pphead == NULL)
	{
		*pphead = SLTBuyNode(x);
	}
	else//不是空链表
	{
		node* cur = *pphead;
		while (cur->next)
		{
			cur = cur->next;
		}//cur走到最后一个节点
		cur->next = SLTBuyNode(x);//链接新创建的节点并加入数据
	}
}

//头插(需要二级指针):
void SLTPushFront(node** pphead, SLDatatype x)
{
	assert(pphead);
	node* newnode = SLTBuyNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

//尾删(如果只有一个节点要把plist置为空,此时需要二级指针,但是有多个节点的话，只需要释放掉最后一个节点，再把上一个节点的next置为空，不需要改变plist，此时不需要二级指针)：
void SLTPopBack(node** pphead)
{
	assert(pphead&&*pphead);
	//如果说只有一个节点:
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;//plist置为空
	}
	else
	{
		//如果说有多个节点:
		node* prev = *pphead;
		node* ptail = *pphead;
		while (ptail->next != NULL)
		{
			prev = ptail;
			ptail = ptail->next;
		}
		free(ptail);
		ptail = NULL;
		prev->next = NULL;
	}
}

//头删:
//不管是只有一个节点还是有多个节点，plist指向的节点需要一直改变，所以需要二级指针
void SLTPopFront(node** pphead)
{
	//链表不能为空:
	assert(*pphead);
	node* frist = *pphead;
	*pphead = (*pphead)->next;//如果只有一个节点的话plist就是NULL了 不用分情况
	free(frist);
	frist = NULL;
}

//查找数据，不需要改变plist的指向，所以只要一级指针就可以
node* SLTFind(node* phead, SLDatatype x)
{
	assert(phead);
	//遍历整个链表:
	while (phead->next != NULL)
	{
		if (phead->data == x)
		{
			return phead;
		}
		phead = phead->next;
	}
	//没找到
	return NULL;
}

//指定位置之前插入数据:
void* SLTInsert(node** pphead, node* pos, SLDatatype x)
{
	assert(pos&&*pphead);
	//如果pos=*pphead 说明是头插:
	node* newnode = SLTBuyNode(x);
	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		node* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		//prev->newnode->pos
		prev->next = newnode;
		newnode->next = pos;
	}
}

//在指定位置之后插⼊数据
void SLTInsertAfter(node* pos, SLDatatype x)
{
	assert(pos);
	node* newnode = SLTBuyNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

//删除指定位置节点
void SLTErase(node** pphead, node* pos)
{
	assert(pos&&pphead&&*pphead);
	if (pos==*pphead)
	{
		//相当于头删:
		SLTPopFront(pphead);
	}
	else
	{
		node* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}	
}

//删除pos之后的节点
void SLTEraseAfter(node* pos)
{
	assert(pos&&pos->next);
	node* temp = pos->next;
	pos->next = pos->next->next;
	free(temp);
	temp = NULL;
}

//销毁链表
void SListDesTroy(node** pphead)
{
	assert(pphead&&*pphead);
	node* cur = *pphead;
	while (cur)
	{
		node* next = cur->next;
		free(cur);
		cur = next;
	}
	*pphead = NULL;
}

